Vertex AI ベクトル検索を使ってみる
daiiz
Heplfeel アーキテクト
ウェブアプリケーションエンジニア
https://gyazo.com/befec87abd51740c4e98496b19f09f50
作家活動
https://gyazo.com/b5af2d6bddc7865c30e3f771640602b8 https://gyazo.com/b5929e993040f86448574c1ab0b2693c
ソフトウェア作家活動
画像を使った画像検索
https://gyazo.com/abf3e4ea34df411c8cae9334f6ef0596
https://gyazo.com/d02a8a0f25ae348735c27d19ecbcb022
検索
仕事でも個人開発でも毎日考えている
本日お見せするのは、個人開発のものです
ベクトル検索したい
生成AIブーム
質の良いEmbeddingが手に入るようになった嬉しさ
ベクトル検索
Elasticsearch
MongoDB
Qdrant
NGT
気楽に実験したい
ローカル環境
セットアップが大変
軽量なベクトルDBを使う手はある
デモ環境
最小構成の価格が高め
実験ごとに課金していくと厳しい
こういうものを勢いよく作りたい
https://gyazo.com/7b15057bee24665a916979f68f4d8b31
仕組み
https://gyazo.com/203b3f5afa248357adc7a143a36cc971
複数の実験で共用できるベクトルDBを用意しよう!!
Vertex AI Matching Engine
GCPのAI系サービスの総称
Matching Engine
最近「ベクトル検索」に改名したらしい?
https://gyazo.com/537a5cc4dada438bc6fca1025760c24b https://cloud.google.com/vertex-ai/docs/vector-search/create-manage-index?hl=ja#index-metadata-file
ハマりポイントとか、すごさとか、話します
作業記録
構成
Datastoreとベクトル検索インデックスに同時に書き込む
https://gyazo.com/111cb7068a38520cef4f4b7d8220d42d
ベクトル化(Embeddingへの変換)
https://gyazo.com/9440af89673d9f1f0580f1aac6093d8f
1635次元
768次元
データの取り込み方法
2つの方式から選べる
バッチ更新(BATCH_UPDATE)
ストリーミング更新(STREAM_UPDATE)
運用中の検索インデックスに対して追加・削除できる
REST APIとして呼び出せる
データの永続化
ベクトル検索はあくまでインデックス
作って壊すことに耐えられるようにしておくべし
永続化は別のDBでやる
Elasticsearchのインデックスの運用方法と似ている
IndexとIndexEndpoint
Index
ベクトル(datapoint)を蓄積して最近傍探索する 更新系の処理はこっちにリクエスト
IndexEndpoint
Indexの探索処理を呼び出せるようにする
取得系の処理はこっちにリクエスト
手順
① Index の作成
② IndexEndpoint の作成
③ Index を IndexEndpoint にデプロイ
Indexの作成
code:config.json
{
"display_name": "demo_202312_6",
"metadata": {
"contentsDeltaUri": "gs://daiiz-demo-index/data/",
"config": {
"dimensions": 1536,
"approximateNeighborsCount": 100,
"shardSize": "SHARD_SIZE_SMALL",
"algorithm_config": {
"treeAhConfig": {}
}
}
},
"indexUpdateMethod": "STREAM_UPDATE"
}
contentsDeltaUriでCloud Storageを紐付ける(必須)
初期データを入れておく
JSONやCSV形式で記述
注意: 30~60分くらいかかる
結構待ち時間がある
初期データが1件でもこれくらいかかる
なんでだろう
設定ミスが判明するまでにも時間がかかる
試行錯誤するときは十分余裕をもって挑むとよい
注意: 初期データ0件はだめ
ストリーミング更新であっても
仮のデータを入れておこう
Indexデプロイ処理の最終段階でエラーになる!!
Indexの更新
datapointの追加・更新
code:js
const datapoints = [
{
datapoint_id: "ID",
restricts: []
}
]
code:js
const apiUrl = https://us-central1-aiplatform.googleapis.com/v1/${indexId}:upsertDatapoints
await fetch(apiUrl, {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: Bearer ${token},
},
body: JSON.stringify({ datapoints }),
});
嬉しさ: idを指定できる
探索結果の datapoint.id を直接メインのDBと照合できる
idの対応関係を保持する必要がない
効率的にupsertできる
嬉しさ: 追加後すぐに検索できる
ストリーミング更新であっても即検索可能
すごい
Indexを検索
クエリベクトルに対する最近傍探索
code:js
const queries = [{
datapoint: {
datapoint_id: "0",
feature_vector: embedding,
restricts: []
neighbor_count: 10,
},
]
code:js
const apiUrl = ${googAiApiOrigin}/v1/${indexEndpointId}:findNeighbors
const res = await fetch(apiUrl, {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: Bearer ${token},
},
// FindNeighborsRequest
body: JSON.stringify({
deployed_index_id: "INDEX_ID",
queries,
}),
});
うまくいっていそう
https://gyazo.com/2550517b29dc30d841c646ef88618782 https://twitter.com/daizplus/status/1734767545926696963
嬉しさ: restrictsが便利
これが最高
複数のデモアプリを同居できる
App=demoapp かつ User=daiiz であるdatapointを対象に探索する
code:js
[
{ "namespace": "User", "allow_list": "daiiz" }, ]
さらに
deny_listもある
注意: 追加後すぐにはベクトル数の情報は変わらない
値に変化がなくても気にしなくてOK
https://gyazo.com/41b6e1c050e643fb079e6a22e0ead0d0
実際に検索してみれば確認できる
定期的にベクトル空間の最適化が行われるらしい
特に何も設定せずに完了メールが来た
ストリーミング更新でも効率的な検索ができる
正しいベクトル数が表示された
コスト感
https://gyazo.com/01164a3282207a0e5b684b16da9568ea
約300円/日
Indexがデプロイされているだけで発生する金額
ちょっと高い!!!
これに加えて
Index Building
Index Streaming Update
いまのところ少額だが、もう少し使い込んでみないとわからない
自分のツイートを全部取り込んでみた
デモ公開、間に合わず(今週中になんとか!)